/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.acap.googlemaps.manejadores;

import com.acap.googlemaps.encapsulados.Coordenadas;
import com.acap.googlemaps.encapsulados.Tipocoordenada;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 * @author acap1505
 */
public class ManejadorCoordenadas {

    private static ManejadorCoordenadas manager = null;

    /**
     * No queremos que nadie pueda construir este objeto, por eso se hace un
     * constructor privado.
     */
    private ManejadorCoordenadas() {
    }

    /**
     * Metodo de instancia.
     *
     * @return
     */
    public static ManejadorCoordenadas getInstance() {
        if (manager == null) {
            manager = new ManejadorCoordenadas();
        }
        return manager;
    }

    /**
     * Metodo para buscar a todas las clientes dentro de la base de datos.
     *
     * Se usan los query's por defecto del objeto.
     *
     * El metodo para manejo de datos que se esta usando es el JPA en el JPA
     * para poder hacer un query a una base de datos se debe crear un objeto
     * Query de la unidad de persistencia de Java este objeto puede acceder a
     * los NamedQuery y tambien a los NativeQuery dependiendo de lo que se
     * quiera hacer.
     *
     * @return
     */
    public List<Coordenadas> getListaCoordenadas() {
        List<Coordenadas> clientes = new ArrayList<>();

        Manejador manejador = new Manejador();
        Connection con = manejador.getConnection();
        try {
            PreparedStatement prep = con.prepareStatement("SELECT * FROM mapwebapp.coordenadas WHERE activo = 1");
            ResultSet rs = prep.executeQuery();

            while (rs.next()) {
                Coordenadas temporal = new Coordenadas();
                temporal.setCoordenada1(rs.getDouble("coordenada1"));
                temporal.setCoordenada2(rs.getDouble("coordenada2"));
                temporal.setDescripcion(rs.getString("descripcion"));
                temporal.setIdcoordenadas(rs.getInt("idcoordenadas"));
                temporal.setTitulo(rs.getString("titulo"));
                temporal.setTipo(ManejadorTipoCoordenada.getInstance().getTipocoordenada(rs.getLong("tipo")));
                temporal.setActivo(rs.getBoolean("activo"));
                clientes.add(temporal);
            }

        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }

        return clientes;
    }
    
    public List<Coordenadas> getListaCoordenadas(Integer tipo) {
        List<Coordenadas> clientes = new ArrayList<>();

        Manejador manejador = new Manejador();
        Connection con = manejador.getConnection();
        try {
            PreparedStatement prep = con.prepareStatement("SELECT * FROM mapwebapp.coordenadas WHERE tipo=? AND activo = 1");
            prep.setInt(1, tipo);
            ResultSet rs = prep.executeQuery();

            while (rs.next()) {
                Coordenadas temporal = new Coordenadas();
                temporal.setCoordenada1(rs.getDouble("coordenada1"));
                temporal.setCoordenada2(rs.getDouble("coordenada2"));
                temporal.setDescripcion(rs.getString("descripcion"));
                temporal.setIdcoordenadas(rs.getInt("idcoordenadas"));
                temporal.setTitulo(rs.getString("titulo"));
                temporal.setTipo(ManejadorTipoCoordenada.getInstance().getTipocoordenada(rs.getLong("tipo")));
                temporal.setActivo(rs.getBoolean("activo"));
                clientes.add(temporal);
            }

        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }

        return clientes;
    }


    /**
     * Metodo para buscar una clientes basandose en el nombre de la clientes.
     * Retorna solo 1 valor, se supone que es unico este nombre de clientes.
     *
     * @param id
     * @return
     */
    public Coordenadas getCoordenadas(Long id) {
        Coordenadas clientes = new Coordenadas();

        Manejador manejador = new Manejador();
        Connection con = manejador.getConnection();
        try {
            PreparedStatement prep = con.prepareStatement("SELECT * FROM mapwebapp.coordenadas WHERE idcoordenadas = ? AND activo = 1");
            prep.setLong(1, id);
            ResultSet rs = prep.executeQuery();

            while (rs.next()) {

                clientes.setCoordenada1(rs.getDouble("coordenada1"));
                clientes.setCoordenada2(rs.getDouble("coordenada2"));
                clientes.setDescripcion(rs.getString("descripcion"));
                clientes.setIdcoordenadas(rs.getInt("idcoordenadas"));
                clientes.setTitulo(rs.getString("titulo"));
                clientes.setTipo(ManejadorTipoCoordenada.getInstance().getTipocoordenada(rs.getLong("tipo")));
                clientes.setActivo(rs.getBoolean("activo"));

            }

        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }

        return clientes;
    }

    /**
     * Determina una lista de clientes basandose en un conjunto de ids.
     *
     * @param ids
     * @return
     */
    public List<Coordenadas> getCoordenadas(List<Long> ids) {
        List<Coordenadas> clientes = new ArrayList<Coordenadas>();

        for (Long id : ids) {
            clientes.add(ManejadorCoordenadas.getInstance().getCoordenadas(id));
        }
        return clientes;
    }

    /**
     * Determina el id de la siguiente clientes
     *
     * @return
     */
    public Long getNext() {
        Long next = null;

        Manejador manejador = new Manejador();
        Connection con = manejador.getConnection();
        try {
            PreparedStatement prep = con.prepareStatement("SELECT count(idcoordenadas) as cuenta FROM mapwebapp.coordenadas");
            ResultSet rs = prep.executeQuery();

            while (rs.next()) {

                next = rs.getLong("cuenta");
            }

        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
        }

        return next + 1;
    }

    /**
     * Metodo para crear un clientes nuevo dentro de la base de datos, este
     * objeto se "persiste" y asi queda guardado completamente dentro de la base
     * de datos.
     *
     * Este metodo crea un nueva clientes con todo lo necesario para poder ser
     * insertado a la base de datos.
     *
     * @param id
     * @param descripcion
     * @return
     */
    public Boolean insertarCoordenadas(Integer idcoordenadas, double coordenada1, double coordenada2, String titulo, String descripcion, Integer tipo) {
        
        try {
            Manejador manejador = new Manejador();
            Connection con = manejador.getConnection();
            try {
                PreparedStatement prep = con.prepareStatement("INSERT INTO mapwebapp.coordenadas(idcoordenadas, coordenada1, coordenada2, titulo, descripcion, tipo) values(?,?,?,?,?,?)");
                prep.setLong(1, idcoordenadas);
                prep.setDouble(2, coordenada1);
                prep.setDouble(3, coordenada2);
                prep.setString(4, titulo);
                prep.setString(5, descripcion);
                prep.setInt(6, tipo);
                
                ResultSet rs = prep.executeQuery();


            } catch (SQLException ex) {
                Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                con.close();
            } catch (SQLException ex) {
                Logger.getLogger(ManejadorCoordenadas.class.getName()).log(Level.SEVERE, null, ex);
            }

            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * Este metodo le da libertad al programador para poder escoger entre si
     * pasarle un conjunto de parametros o solo el clientes ya creado.
     *
     * @param clientes
     * @return
     */
    public Boolean insertarCoordenadas(Coordenadas clientes) {
        Manejador manejador = new Manejador();
        try {
            //Iniciando una transaccion
            manejador.getEntityManager().getTransaction().begin();
            //Insertando el objeto
            manejador.getEntityManager().persist(clientes);
            //Guardandolo en la base de datos con un commit
            manejador.getEntityManager().getTransaction().commit();
            manejador.getEntityManager().close();

            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * Este metodo se utiliza para actualizar la data de la clientes pasandole
     * todos los parametros correspondientes.
     *
     * @param id
     * @param descripcion
     * @return
     */
    public Boolean actualizarCoordenadas(Integer idcoordenadas, double coordenada1, double coordenada2, String titulo, String descripcion, Boolean activo, Tipocoordenada tipo) {
        Coordenadas clientes = new Coordenadas(idcoordenadas, coordenada1, coordenada2, titulo, descripcion, activo);
        clientes.setTipo(tipo);
        Manejador manejador = new Manejador();
        try {
            // Iniciando transiccion a base de datos.
            manejador.getEntityManager().getTransaction().begin();

            // Modificando el objeto.
            manejador.getEntityManager().merge(clientes);

            // Comit a la base de datos.
            manejador.getEntityManager().getTransaction().commit();
            manejador.getEntityManager().close();

            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * Este metodo permite actualizar la clientes basandose en un objeto
     * clientes WARNING: NO USAR UN OBJETO NULLO EN NINGUN MOMENTO.
     *
     * @param clientes
     * @return
     */
    public Boolean actualizarCoordenadas(Coordenadas clientes) {
        Manejador manejador = new Manejador();
        try {

            // Iniciando transiccion a base de datos.
            manejador.getEntityManager().getTransaction().begin();

            // Modificando el objeto.
            manejador.getEntityManager().merge(clientes);

            // Comit a la base de datos.
            manejador.getEntityManager().getTransaction().commit();
            manejador.getEntityManager().close();

            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public static void main(String[] args) {
        for (Coordenadas temp : ManejadorCoordenadas.getInstance().getListaCoordenadas()) {
            System.out.println(temp.getTipo().getIcono().getIconosSrc());
        }
    }
}